/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
*/

#include "list.h"

struct list_t *list_create()
{
    struct list_t *t;
	t = (struct list_t *)malloc(sizeof(struct list_t));
	memset(t, 0, sizeof(struct list_t));
	return t;
}

void list_destroy(struct list_t *l)
{
    if (l != NULL)
        list_clear(l);
}

void list_add(struct list_t *list, void *data)
{
    if (list->data == NULL)
    {
        list->data = data;
    }
    else
    {
        struct list_t *current, *new;

        new = (struct list_t *)malloc(sizeof(struct list_t));
        memset(new, 0, sizeof(struct list_t));
        new->data = data;

        current = list;
        /* Follow the links through the list until we hit the end */
        while(current->next != NULL)
            current = current->next;

        current->next = new;
    }
    return;
}

void list_execute(struct list_t *l, void (*functionpointer)(void *data))
{
    struct list_t *c;
    c = l;

    while(c != NULL)
    {
        (*functionpointer)(c->data);
        c = c->next;
    }
}

void list_clear(struct list_t *l)
{
    struct list_t *current, *nextnode;
    current = l;

    /* Go through each member of the list and print it out */
    while(current != NULL)
    {
        nextnode = current->next;

        /* Should've already been performed by a custom function, but just incase.. */
        if (current->data != NULL)
        {
            free(current->data);
        }

        free(current);
        current = nextnode;
    }
    free(l);
}
